﻿using NLua;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace NLuaBenchmarkDotNetTest
{
    using System;
    using System.Collections;
    using System.Collections.Generic;

    /// <summary>
    /// 数学工具类，提供常用统计函数
    /// </summary>
    public static class MathUtils
    {
        /// <summary>
        /// 计算集合最大值
        /// </summary>
        /// <param name="collection">支持 IEnumerable 的集合（数组、List等）</param>
        /// <returns>集合中的最大值</returns>
        /// <exception cref="ArgumentNullException">输入集合为空</exception>
        /// <exception cref="ArgumentException">集合包含无效元素或为空</exception>
        public static double Max(IEnumerable collection)
        {
            if (collection == null)
                throw new ArgumentNullException(nameof(collection), "输入集合不能为null");

            double max = double.MinValue;
            bool hasElements = false;

            foreach (var item in collection)
            {
                double current = ConvertToDouble(item);
                if (!hasElements)
                {
                    max = current;
                    hasElements = true;
                }
                else if (current > max)
                {
                    max = current;
                }
            }

            if (!hasElements)
                throw new ArgumentException("集合中不包含有效元素");
            return max;
        }

        /// <summary>
        /// 计算集合最小值
        /// </summary>
        /// <param name="collection">支持 IEnumerable 的集合</param>
        /// <returns>集合中的最小值</returns>
        /// <exception cref="ArgumentNullException">输入集合为空</exception>
        /// <exception cref="ArgumentException">集合包含无效元素或为空</exception>
        public static double Min(IEnumerable collection)
        {
            if (collection == null)
                throw new ArgumentNullException(nameof(collection), "输入集合不能为null");

            double min = double.MaxValue;
            bool hasElements = false;

            foreach (var item in collection)
            {
                double current = ConvertToDouble(item);
                if (!hasElements)
                {
                    min = current;
                    hasElements = true;
                }
                else if (current < min)
                {
                    min = current;
                }
            }

            if (!hasElements)
                throw new ArgumentException("集合中不包含有效元素");
            return min;
        }

        /// <summary>
        /// 计算集合平均值
        /// </summary>
        /// <param name="collection">支持 IEnumerable 的集合</param>
        /// <returns>算术平均值</returns>
        /// <exception cref="ArgumentNullException">输入集合为空</exception>
        /// <exception cref="ArgumentException">集合包含无效元素或为空</exception>
        public static double Mean(IEnumerable collection)
        {
            if (collection == null)
                throw new ArgumentNullException(nameof(collection), "输入集合不能为null");

            double sum = 0;
            int count = 0;

            foreach (var item in collection)
            {
                double current = ConvertToDouble(item);
                sum += current;
                count++;
            }

            if (count == 0)
                throw new ArgumentException("集合中不包含有效元素");
            return sum / count;
        }
        /// <summary>
        /// 计算集合中位数
        /// </summary>
        /// <param name="collection">支持 IEnumerable 的集合</param>
        /// <returns>排序后的中间值（偶数个元素时取平均值）</returns>
        /// <exception cref="ArgumentNullException">输入集合为空</exception>
        /// <exception cref="ArgumentException">集合包含无效元素或为空</exception>
        public static double Median(IEnumerable collection)
        {
            if (collection == null)
                throw new ArgumentNullException(nameof(collection), "输入集合不能为null");

            // 转换为有序列表
            List<double> values = new List<double>();
            foreach (var item in collection)
            {
                values.Add(ConvertToDouble(item));
            }

            if (values.Count == 0)
                throw new ArgumentException("集合中不包含有效元素");

            // 排序操作（不修改原始集合）
            values.Sort();

            // 计算中位数
            int count = values.Count;
            int midIndex = count / 2;

            // 奇数个元素
            if (count % 2 != 0)
            {
                return values[midIndex];
            }
            // 偶数个元素
            else
            {
                return (values[midIndex - 1] + values[midIndex]) / 2.0;
            }
        }
        /// <summary>
        /// 安全索引访问器（支持Lua数组的0-based索引规则）
        /// </summary>
        /// <param name="collection">目标集合（支持IList接口的集合）</param>
        /// <param name="index">索引值（支持负索引倒查）</param>
        /// <param name="strict">严格模式校验元素连续性</param>
        /// <returns>索引位置的元素</returns>
        /// <exception cref="ArgumentNullException">输入集合为空</exception>
        /// <exception cref="ArgumentException">集合类型不合法或索引无效</exception>
        public static object At(IEnumerable collection, int index, bool strict = false)
        {
            // 参数基础校验
            if (collection == null)
                throw new ArgumentNullException(nameof(collection), "输入集合不能为null");

            // 类型安全转换
            IList list = collection as IList;
            if (list == null)
                throw new ArgumentException("输入集合必须实现IList接口", nameof(collection));

            // 获取有效长度
            int count = list.Count;
            if (count == 0)
                throw new ArgumentException("集合中不包含有效元素", nameof(collection));

            // 索引转换逻辑
            int adjustedIndex = index >= 0 ? index : count + index;

            // 边界校验
            if (adjustedIndex < 0 || adjustedIndex >= count)
            {
                string msg = $"索引 {index} 超出有效范围 [{-count}, {count - 1}]";
                throw new ArgumentOutOfRangeException(nameof(index), msg);
            }

            // 严格模式校验
            if (strict)
            {
                // 校验是否存在null元素
                for (int i = 0; i < count; i++)
                {
                    if (list[i] == null)
                    {
                        throw new ArgumentException($"严格模式检测到空元素 @ 位置 {i}");
                    }
                }
            }

            return ConvertToDouble(list[adjustedIndex]);
        }
        // 转换方法复用已有实现
        private static double ConvertToDouble(object item)
        {
            try
            {
                return Convert.ToDouble(item);
            }
            catch (InvalidCastException)
            {
                throw new ArgumentException($"元素 {item} 包含非数字类型");
            }
        }
    }

    // NLua 注册类
}
